Tópicos adicionais com ggplot2

Esse breve tutorial fornece um guia para alguns recursos adicionais do ggplot2. Também exploramos como preparar nossos dados com dplyr para facilitar o trabalho com ggplot2.

Mais geometrias

Existe uma variedade de geometrias que podemos usar como camadas para visualizar os nossos dados. Vamos continuar com o nosso analise de dados de Fakeland.

library(readr)
library(ggplot2)
url_fake_data <- "https://raw.githubusercontent.com/leobarone/cebrap_lab_programacao_r/master/data/fake_data_2.csv"
fake <- read_delim(url_fake_data, delim = ";", col_names = T)
## Parsed with column specification:
## cols(
##   idade = col_integer(),
##   sexo = col_character(),
##   educ = col_character(),
##   partido = col_character(),
##   candidato = col_character(),
##   renda = col_double(),
##   filhos = col_integer()
## )

Uma geometria muito útil é geom_text, que coloca como formas geométricas os textos mesmos. Por exemplo, nós podemos especificar um gráfico de dispersão onde os pontos refletem o nome de candidato em que as pessoas votaram, usando o parâmetro ‘label’.

ggplot(fake) +
  geom_text(aes(x=idade,y=renda,label=candidato))

Outro geometria útil é geom_tile que tem uma forte conexão com mapas “raster” que discutiremos mais adiante no curso. Especificamos variáveis x e y, e também uma variável de ‘fill’ que se aplica a cada célula de interseção de x e y.

ggplot(fake) +
  geom_tile(aes(x=idade,y=educ, fill=renda))

Pipes e Gráficos de linha

Gráficos de linha exigem, em geral, um pouco mais de preparação de nossos dados. A variável y pode ser discreta ou contínua, mas precisa ser ordenado para que as linhas façam sentido. Para que podemos transformar os nossos dados na mesma linha de código onde criamos o nosso gráfico, vamos aprender primeiramente como a usar ggplot2 com o pipe:

library(tidyverse)
## -- Attaching packages ---------------------------------------------------------------------------- tidyverse 1.2.1 --
## v tibble  1.4.2     v dplyr   0.7.4
## v tidyr   0.8.0     v stringr 1.3.0
## v purrr   0.2.4     v forcats 0.3.0
## -- Conflicts ------------------------------------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
## x dplyr::vars()   masks ggplot2::vars()
fake %>% ggplot() +
  geom_point(aes(x=idade,y=renda))

Só precisamos pegar o data.frame fora do ggplot2 e colocá-lo antes do pipe. Note uma coisa chata: existe dois símbolos conetando os nossas ações agora: um pipe ( %>% ) e um “+”. Usamos o pipe com data.frames, e o “+” com camadas de gráficos depois da linha ggplot2().

Com este novo fluxo de trabalho, agora é fácil transformar nossos dados antes de visualizar. Por exemplo, podemos visualizar apenas os dados para as mulheres.

fake %>% filter(sexo=="Female") %>%
  ggplot() +
  geom_point(aes(x=idade,y=renda))

Para criar um gráfico de linha vamos usar ‘idade’ como nossa variável ordenada e, portanto, precisamos resumir os dados por idade. Vamos analisar a renda média por idade

fake %>% group_by(idade) %>%
  summarize(renda_media=mean(renda,na.rm=T))
## # A tibble: 26 x 2
##    idade renda_media
##    <int>       <dbl>
##  1    21       8397.
##  2    24       5717.
##  3    26       9014.
##  4    28      14906.
##  5    29      11174.
##  6    30       6295.
##  7    31      11993.
##  8    32      15770.
##  9    33      18409.
## 10    34      16935.
## # ... with 16 more rows

Já criamos um novo tamanho e forma da tabela para analisar. Podemos usar os novos variáveis em nosso gráfico.

fake %>% group_by(idade) %>%
  summarize(renda_media=mean(renda,na.rm=T)) %>%
  ggplot() +
  geom_line(aes(x=idade, y=renda_media))

E se quisermos ter duas linhas, uma para cada sexo? Precisamos reorganizar nossos dados e incluir um parâmetro ‘group’ em nossa chamada para ggplot2. Isso é essencial para que o ggplot2 saiba como desenhar as linhas.

fake %>% group_by(idade,sexo) %>%
  summarize(renda_media=mean(renda,na.rm=T)) %>%
  ggplot() +
  geom_line(aes(x=idade, y=renda_media, group=sexo))

Claro que precisamos distinguir a cor das linhas também.

fake %>% group_by(idade,sexo) %>%
  summarize(renda_media=mean(renda,na.rm=T)) %>%
  ggplot() +
  geom_line(aes(x=idade, y=renda_media, group=sexo, colour=sexo))

Exercício

Accesse o banco de dados flights no pacote nycflights13. Transforme os dados e crie um gráfico de linha com meses no eixo horixontal, o atraso média de partida ( dep_delay) no eixo vertical, e linhas separadas para cada aeroporto de origem.

library(nycflights13)

flights %>% group_by(month,origin) %>%
  summarize(avg_dep_delay=mean(dep_delay,na.rm=T)) %>%
  ggplot() +
  geom_line(aes(x=month,y=avg_dep_delay,group=origin,colour=origin))

Controlando cores com ‘scales’

O ggplot2 usa cores defaults. Claro que podemos controlar os cores usando mais um elemento da gramática dos gráficos, ‘scales’. Adicionamos mais uma linha de código no final para controlar quais cores o ggplot2 deve usar. Infelizmente, precisamos tomar muito cuidado com o tipo de scale, que precisa corresponder ao tipo de nossos dados e também se estamos colorindo um ponto/linha (‘colour’) ou preenchendo uma área (‘fill’). Use o tabela debaixo como uma guia:

Tipo de dados Color (point, line) Fill (area)
Continuo scale_color_gradient(low=“color1”,high=“color2”) scale_fill_gradient(low=“color1”,high=“color2”)
Discreto scale_color_brewer(palette=“pre-definido”) scale_fill_brewer(palette=“pre-definido”)

Para os cores e palettes, podemos usar vários tipos de referências: nomes, rgb, hex etc. Mas é difícil escolher boas cores - é melhor usar um site como http://colorbrewer2.org

Vamos modificar os cores de nosso gráfico de linha. O nosso variável distinguida pela cor é o sexo, que é discreto, e nós queremos colorir as linhas, não as áreas, então precisamos usar scale_color_brewer. Eu gosto de um escala/palette se chame ‘Accent’ então adicionamos uma nova linha no código.

fake %>% group_by(idade,sexo) %>%
  summarize(renda_media=mean(renda,na.rm=T)) %>%
  ggplot() +
  geom_line(aes(x=idade, y=renda_media, group=sexo, colour=sexo)) +
  scale_color_brewer(palette="Accent")

Para ilustrar o uso de uma escala contínua e de área, voltamos para o gráfico de geom_tile. Agora, precisamos usar scale_fill_gradient e especificar o cor de valores baixos e o cor de valores altos.

ggplot(fake) +
  geom_tile(aes(x=idade,y=educ, fill=renda)) +
  scale_fill_gradient(low="yellow",high="red")

Exercício

Com o banco de dados flights, filtrar os dados para voos partindo do aeroporto LGA dia 20 de maio (‘month’ e ‘day’). Depois, crie um gráfico de dispersão/texto que compara a hora de partida com distancia, que coloca os nomes de destinos no gráfico, e, usando um ‘scale’, para que o cor de cada texto refleto o atraso de partido deste voo.

Gráficos interativas e animações

Se você estiver trabalhando com um site online (e não um PDF), talvez queira tornar seu gráfico interativo para que os usuários possam explorar cada ponto de dados. Isso é fácil com o pacote plotly e o comando ggplotly. Salvamos nosso gráfico como um objeto e, em seguida, usamos ggplotly.

install.packages("plotly")
## Installing package into 'C:/Users/Jonny/Documents/R/win-library/3.4'
## (as 'lib' is unspecified)
## package 'plotly' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\Jonny\AppData\Local\Temp\RtmpQX6MLw\downloaded_packages
library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
graf_1 <- fake %>% group_by(idade,sexo) %>%
  summarize(renda_media=mean(renda,na.rm=T)) %>%
  ggplot() +
  geom_line(aes(x=idade, y=renda_media, group=sexo, colour=sexo)) 

graf_1 %>%
  ggplotly()

Este pacote também ajuda a transformar gráficos para animações. Podemos usar o mesmo fluxo de trabalho acima, e só precisamos especificar o parâmetro ‘frame’ em ggplot2 para a variável que queremos a mudar com cada slide da animação. Para ilustrar, vamos analisar um gráfico de dispersão simples, que muda cada slide para filtrar os dados por número de filhos.Toque ‘play’ no gráfico produzido pelo código debaixo para ver a animação.

graf_2 <- fake %>%
  ggplot() +
  geom_point(aes(x=idade, y=renda, frame=filhos))
## Warning: Ignoring unknown aesthetics: frame
graf_2 %>%
  ggplotly()

Gráficos em Rmarkdown

Para incluir o seu gráfico num documento de Rmarkdown, apenas colocar o código dentro de um chunk (sem salvar como objeto). Normalmente, usamos um chunk separado para cada gráfico. Podemos controlar o tamanho do gráfico com os parametros de chunk, ‘fig.height’ and ‘fig.width’, em inches, eg. ‘fig.height=5’.

Exercício

Compilar um documento HTML que inclui o gráfico do exercício anterior. Tornar este gráfico para uma animação para que cada slide é um dia diferente em maio.